<!DOCTYPE html>
<html>
<head>
    <title>音频录制实时播放</title>
</head>
<body>
    <button id="start">开始</button>
    <button id="stop" disabled>停止</button>
    <p id="status">准备就绪</p>

    <script>
        let audioContext = null;
        let inputNode = null;
        let processor = null;
        let mediaStream = null;

        // 音频参数配置
        const config = {
            sampleRate: 44100,
            bufferSize: 512,
            bitsPerSample: 16
        };

        // 初始化音频上下文
        function initAudioContext() {
            try {
                audioContext = new (window.AudioContext || window.webkitAudioContext)({
                    sampleRate: config.sampleRate
                });
                
                if (audioContext.sampleRate !== config.sampleRate) {
                    alert('不支持44100Hz采样率');
                    return false;
                }
                return true;
            } catch (e) {
                console.error('音频上下文初始化失败:', e);
                return false;
            }
        }

        // 创建处理节点
        function createProcessor() {
            processor = audioContext.createScriptProcessor(
                config.bufferSize,
                1,  // 单声道输入
                1   // 单声道输出
            );

            processor.onaudioprocess = (event) => {
                const input = event.inputBuffer.getChannelData(0);
                const output = event.outputBuffer.getChannelData(0);
                
                // PCM16转换处理
                const pcm16 = new Int16Array(input.length);
                console.log(input);
                for (let i = 0; i < input.length; i++) {
                    const s = Math.max(-1, Math.min(1, input[i]));
                    // pcm16[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
                    pcm16[i]=s*32767;
                }
                console.log(pcm16.buffer);
                console.log(0x8000, 0x7FFF);
                // 转换回浮点数用于播放
                const audioData = new Int16Array(pcm16.buffer);
                for (let i = 0; i < pcm16.length; i++) {
                    output[i] = audioData[i] / (audioData[i] < 0 ? 0x8000 : 0x7FFF);
                }
            };
        }

        // 开始录音
        async function startRecording() {
            try {
                mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
                
                if (!initAudioContext()) return;
                createProcessor();
                
                inputNode = audioContext.createMediaStreamSource(mediaStream);
                inputNode.connect(processor);
                processor.connect(audioContext.destination);
                
                document.getElementById('status').textContent = '录音中...';
            } catch (err) {
                console.error('录音设备获取失败:', err);
                document.getElementById('status').textContent = '麦克风访问被拒绝';
            }
        }

        // 停止录音
        function stopRecording() {
            if (processor) {
                processor.disconnect();
                processor = null;
            }
            if (inputNode) {
                inputNode.disconnect();
                inputNode = null;
            }
            if (mediaStream) {
                mediaStream.getTracks().forEach(track => track.stop());
            }
            document.getElementById('status').textContent = '已停止';
        }

        // 事件绑定
        document.getElementById('start').addEventListener('click', () => {
            startRecording();
            document.getElementById('start').disabled = true;
            document.getElementById('stop').disabled = false;
        });

        document.getElementById('stop').addEventListener('click', () => {
            stopRecording();
            document.getElementById('start').disabled = false;
            document.getElementById('stop').disabled = true;
        });
    </script>
</body>
</html>
